bitkeeper revision 1.1159.1.146 (4140f4e4MoMfo8OhzKj1hieTq2id2A)
authorkaf24@freefall.cl.cam.ac.uk <kaf24@freefall.cl.cam.ac.uk>
Fri, 10 Sep 2004 00:27:16 +0000 (00:27 +0000)
committerkaf24@freefall.cl.cam.ac.uk <kaf24@freefall.cl.cam.ac.uk>
Fri, 10 Sep 2004 00:27:16 +0000 (00:27 +0000)
Allow a p.t. to be mapped at multiple different virtual addresses. This is
a pretty benign situation right now (although writable pagetables will fail,
exiting the domain). In future it may well cause significant slowdown to
writable pagetables and/or shadow pagetables. So beware!!

xen/arch/x86/memory.c
xen/include/asm-x86/mm.h

index 640181a6cca3815af8aa06fdb270bc3382901c0a..bae38bb04d9144dc8b5177b818ccd431c37735cb 100644 (file)
@@ -913,10 +913,9 @@ int get_page_type(struct pfn_info *page, u32 type)
             }
             else if ( unlikely((x & PGT_va_mask) != (type & PGT_va_mask)) )
             {
-                /* The va backpointer wasn't mutable, and is different. */
-                MEM_LOG("Unexpected va backpointer (saw %08x != exp %08x)"
-                        " for pfn %08lx\n", x, type, page_to_pfn(page));
-                return 0;
+                /* This table is potentially mapped at multiple locations. */
+                nx &= ~PGT_va_mask;
+                nx |= PGT_va_unknown;
             }
         }
        else if ( unlikely(!(x & PGT_validated)) )
@@ -1786,12 +1785,21 @@ int ptwr_do_page_fault(unsigned long addr)
         page = &frame_table[pfn];
         if ( (page->u.inuse.type_info & PGT_type_mask) == PGT_l1_page_table )
         {
-            pl2e = &linear_l2_table[(page->u.inuse.type_info &
-                                     PGT_va_mask) >> PGT_va_shift];
+            u32 va_mask = page->u.inuse.type_info & PGT_va_mask;
+
+            /*
+             * XXX KAF: This version of writable pagetables doesn't need
+             * to know the back pointer at all, as it is unnecessary to be
+             * unlinking the page table --- FIXME!
+             */
+            if ( unlikely(va_mask >= PGT_va_unknown) )
+                domain_crash();
+            va_mask >>= PGT_va_shift;
+
+            pl2e = &linear_l2_table[va_mask];
             PTWR_PRINTK(PP_ALL, ("page_fault on l1 pt at va %08lx, pt for %08x"
                                  ", pfn %08lx\n", addr,
-                                 ((page->u.inuse.type_info & PGT_va_mask) >>
-                                  PGT_va_shift) << L2_PAGETABLE_SHIFT, pfn));
+                                 va_mask << L2_PAGETABLE_SHIFT, pfn));
 
             if ( l2_pgentry_val(*pl2e) >> PAGE_SHIFT != pfn )
             {
@@ -1832,8 +1840,7 @@ int ptwr_do_page_fault(unsigned long addr)
                 nl2e = mk_l2_pgentry((l2_pgentry_val(*pl2e) & ~_PAGE_PRESENT));
                 update_l2e(pl2e, *pl2e, nl2e);
 
-                ptwr_info[cpu].disconnected_pteidx =
-                    (page->u.inuse.type_info & PGT_va_mask) >> PGT_va_shift;
+                ptwr_info[cpu].disconnected_pteidx = va_mask;
                 PTWR_PRINTK(PP_A, ("[A] now pl2e %p l2e %08lx              "
                                    "taf %08x/%08x\n", pl2e,
                                    l2_pgentry_val(*pl2e),
index 50d598832951c09d1cb32de804c695d635177ff4..3a4db629caf8bf39eb11d8067b41d936f4e925aa 100644 (file)
@@ -77,7 +77,10 @@ struct pfn_info
  /* The 10 most significant bits of virt address if this is a page table. */
 #define PGT_va_shift        17
 #define PGT_va_mask         (((1<<10)-1)<<PGT_va_shift)
-#define PGT_va_mutable      PGT_va_mask /* va backpointer is mutable? */
+ /* Is the back pointer still mutable (i.e. not fixed yet)? */
+#define PGT_va_mutable      (((1<<10)-1)<<PGT_va_shift)
+ /* Is the back pointer unknown (e.g., p.t. is mapped at multiple VAs)? */
+#define PGT_va_unknown      (((1<<10)-2)<<PGT_va_shift)
  /* 17-bit count of uses of this frame as its current type. */
 #define PGT_count_mask      ((1<<17)-1)